package com.youlu.campus.admin.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.youlu.campus.admin.auth.dto.JwtDTO;
import lombok.extern.slf4j.Slf4j;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 *
 * @author zhuhuaiqi
 */
@Slf4j
public class JwtUtil {

    public static final String SECRET = "youlu#@2020";

    private static final int TIME_OUT_MINUTES = 120;

    private static final ZoneId ZONE = ZoneId.systemDefault();

    public static JwtDTO generateToken(String userId, Map<String, Object> payload) {

        Calendar nowTime = Calendar.getInstance();

        nowTime.add(Calendar.MINUTE, TIME_OUT_MINUTES);

        Date expiresDate = nowTime.getTime();

        JWTCreator.Builder jwt = JWT.create().withAudience(userId)   //签发对象
                .withIssuedAt(new Date())    //发行时间
                .withExpiresAt(expiresDate);  //有效时间

        for (Map.Entry<String, Object> entry: payload.entrySet()) {
           jwt.withClaim(entry.getKey(), entry.getKey());
        }

        String token = jwt.sign(Algorithm.HMAC256(SECRET));   //加密

        JwtDTO jwtDto = new JwtDTO();
        jwtDto.setToken(token);
        jwtDto.setTimestamp(nowTime.getTime().getTime());
        jwtDto.setExpiration(expiresDate.getTime());

        return jwtDto;
    }

    /**
     * 校验token是否正确
     * @param token  密钥
     * @return 是否正确
     */
    public static boolean verify(String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .build();
            verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获取签发对象
     */
    public static String getAudience(String token) {
        String audience = null;
        try {
            audience = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException e) {
            //这里是token解析失败
            log.error("getAudience error", e);
        }
        return audience;
    }

    /**
     * 通过载荷名字获取载荷的值
     */
    public static Claim getClaimByName(String token, String name){
        return JWT.decode(token).getClaim(name);
    }

}
